home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2b.lha / p4-1.2b / lib / p4_bm.c < prev    next >
C/C++ Source or Header  |  1993-02-06  |  13KB  |  456 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. int bm_start(argc, argv)
  5. int *argc;
  6. char **argv;
  7. {
  8.     int bm_switch_port;
  9.  
  10.     sprintf(whoami_p4, "p0_%d", getpid());
  11.     p4_dprintfl(90,"entering bm_start\n");
  12.  
  13.     trap_sig_errs();        /* Errors can happen any time */
  14.  
  15.     logging_flag = FALSE;
  16.     globmemsize = GLOBMEMSIZE;
  17.     sserver_port = 753;
  18.  
  19.     process_args(argc, argv);
  20.  
  21. #   ifdef SYSV_IPC
  22.     sysv_num_shmids = 0;
  23.     sysv_shmid[0]  = -1;
  24.     sysv_semid0 = init_sysv_semset(0);
  25. #   endif
  26.  
  27.     MD_initmem(globmemsize);
  28.     alloc_global();  /* sets p4_global */
  29.  
  30.     if (*bm_outfile)
  31.     {
  32.     freopen(bm_outfile, "w", stdout);
  33.     freopen(bm_outfile, "w", stderr);
  34.     }
  35.  
  36.     p4_local = alloc_local_bm();
  37.     if (p4_local == NULL)
  38.     p4_error("p4_initenv: alloc_local_bm failed\n", NULL);
  39.  
  40.     MD_initenv();
  41.     bm_switch_port = getswport(p4_global->my_host_name);
  42.     usc_init();
  43.  
  44.     /* big master installing himself */
  45.     install_in_proctable(0, (-1), getpid(), p4_global->my_host_name, 
  46.              0, P4_MACHINE_TYPE, bm_switch_port);
  47.  
  48.     p4_local->my_id = 0;
  49.  
  50.     if (logging_flag)
  51.     ALOG_ENABLE;
  52.     else
  53.     ALOG_DISABLE;
  54.  
  55.     return (0);
  56. }
  57.  
  58. int p4_create_procgroup()
  59. {
  60.  
  61.     p4_dprintfl(90,"entering p4_create_procgroup\n");
  62.     if (p4_local->my_id != 0)
  63.     return(0);
  64.     if ((p4_local->procgroup = read_procgroup()) == NULL)
  65.     return (-1);
  66.     p4_startup(p4_local->procgroup);
  67.     return(0);
  68. }
  69.  
  70.  
  71. int p4_startup(pg)
  72. struct p4_procgroup *pg;
  73. {
  74.     int i, nslaves, unused_flag;
  75.     int listener_port, listener_fd;
  76.     struct bm_rm_msg bm_msg;
  77.     struct p4_procgroup_entry *local_pg;
  78.  
  79.     p4_dprintfl(90,"entering p4_startup\n");
  80.  
  81.     if (p4_global == NULL)
  82.     p4_error("p4 not initialized; perhaps p4_initenv not called",0);
  83.  
  84.     procgroup_to_proctable(pg);
  85.     if (pg->num_entries > 1)
  86.     p4_global->local_communication_only = FALSE;
  87.  
  88. #   ifdef CAN_DO_SOCKET_MSGS
  89.     if (!p4_global->local_communication_only)
  90.     {
  91.     net_setup_anon_listener(10, &listener_port, &listener_fd);
  92.     p4_global->listener_port = listener_port;
  93.     p4_global->listener_fd = listener_fd;
  94.     p4_dprintfl(90, "setup listener on port %d fd %d\n",
  95.             listener_port, listener_fd);
  96.     p4_global->proctable[0].port = listener_port;
  97.     SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  98.     }
  99. #   endif
  100.  
  101.     setup_conntab();
  102.  
  103.     p4_lock(&p4_global->slave_lock);
  104.     if ((nslaves = create_bm_processes(pg)) < 0)
  105.     return (-1);
  106.     if (!p4_am_i_cluster_master())  /* I was forked in create_bm_processes */
  107.     return(0);
  108.  
  109. #   ifdef CAN_DO_SOCKET_MSGS
  110.     if (create_remote_processes(pg) < 0)
  111.     return (-1);
  112. #   endif
  113.  
  114.     /* let local slaves use proc table to identify themselves */
  115.     p4_unlock(&p4_global->slave_lock); 
  116.  
  117.     send_proc_table();  /* to remote masters */
  118.  
  119. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  120.     /* send initial info and proctable to local slaves */
  121.     /* must use p4_i_to_n procs because node slave 
  122.        does not know if the msg is forwarded from bm */
  123.     local_pg = &(pg->entries[0]);
  124.     bm_msg.type = p4_i_to_n(INITIAL_INFO);
  125.     bm_msg.numinproctab = p4_i_to_n(p4_global->num_in_proctable);
  126.     bm_msg.numslaves = p4_i_to_n(local_pg->numslaves_in_group);
  127.     bm_msg.debug_level = p4_i_to_n(remote_debug_level);
  128.     bm_msg.memsize = p4_i_to_n(globmemsize);
  129.     bm_msg.logging_flag = p4_i_to_n(logging_flag);
  130.     strcpy(bm_msg.application_id, p4_global->application_id);
  131.     strcpy(bm_msg.version, p4_version());
  132.     strcpy(bm_msg.pgm, local_pg->slave_full_pathname);
  133.     for (i = 1; i <= nslaves; i++)
  134.     {
  135.     p4_dprintfl(90,"sending initinfo to slave %d of %d\n",i,nslaves);
  136. #       if defined(IPSC860)
  137.     csend((long) INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg), 
  138.           (long) i, (long) NODE_PID);
  139.     csend((long) INITIAL_INFO, p4_global->proctable, 
  140.           (long) sizeof(p4_global->proctable), (long) i, (long) NODE_PID);
  141. #       endif
  142. #       if defined(CM5)
  143.     CMMD_send_noblock(i, INITIAL_INFO, &bm_msg, sizeof(struct bm_rm_msg));
  144.     CMMD_send_noblock(i, INITIAL_INFO, p4_global->proctable, sizeof(p4_global->proctable));
  145. #       endif
  146. #       if defined(NCUBE)
  147.     nwrite(&bm_msg, sizeof(struct bm_rm_msg), i, INITIAL_INFO, &unused_flag);
  148.     nwrite(p4_global->proctable, sizeof(p4_global->proctable), i, INITIAL_INFO, &unused_flag);
  149. #       endif
  150.     p4_dprintfl(90,"sent initinfo to slave %d of %d\n",i,nslaves);
  151.     }
  152. #   endif
  153.  
  154.     p4_global->low_cluster_id = 
  155.     p4_local->my_id - p4_global->proctable[p4_local->my_id].slave_idx;
  156.     p4_global->hi_cluster_id = 
  157.     p4_global->low_cluster_id + p4_global->local_slave_count + 1;
  158.  
  159.     /* 
  160.        sync with local slaves thus insuring that they have the proctable before 
  161.        syncing with remotes (this keeps remotes from interrupting the local 
  162.        processes too early; then re-sync with local slaves (thus permitting them
  163.        to interrupt remotes)
  164.     */
  165.  
  166.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  167.     /* 
  168.        NEED A SYNC WITH LOCALS THAT DOES A BARRIER WITH PROCS THAT SHARE
  169.        MEMORY AND MP BARRIER WITH OTHER "LOCAL" PROCESSES 
  170.     */
  171.     sync_with_remotes();
  172.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  173.  
  174.  
  175.     return (0);
  176. }
  177.  
  178. int create_bm_processes(pg)
  179. struct p4_procgroup *pg;
  180. {
  181.     struct p4_procgroup_entry *local_pg;
  182.     struct listener_data *l;
  183.     int i, nslaves, end_1, end_2;
  184.     int slave_pid, listener_pid;
  185.     int slave_idx, listener_fd;
  186.     int port, switch_port, from, type, unused_flag;
  187.     struct bm_rm_msg bm_msg;
  188.  
  189.     p4_dprintfl(90,"entering create_bm_processes\n");
  190.     local_pg = &(pg->entries[0]);
  191.  
  192.     nslaves = local_pg->numslaves_in_group;
  193. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  194.     if (nslaves > P4_MAX_MSG_QUEUES)
  195.     p4_error("more slaves than msg queues \n", nslaves);
  196. #   endif
  197.  
  198. /* alloc listener local data since this proc will eventually become listener */
  199. #   ifdef CAN_DO_SOCKET_MSGS
  200.     if (!(p4_global->local_communication_only))
  201.     {
  202.     listener_fd = p4_global->listener_fd;
  203.     listener_info = alloc_listener_info();
  204.     l = listener_info;
  205.     get_pipe(&end_1, &end_2);
  206.     }
  207. #   endif
  208.  
  209. #   ifdef TCMP
  210.     tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  211. #   endif
  212.  
  213. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  214.     for (i = 1; i <= nslaves; i++)
  215.     {
  216.     p4_dprintfl(90,"doing initial sync with local slave %d\n",i);
  217. #       if defined(IPSC860)
  218.     csend((long) SYNC_MSG, &bm_msg, (long) sizeof(struct bm_rm_msg), 
  219.           (long) i, (long) NODE_PID);
  220.     crecv(INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg));
  221. #       endif
  222. #       if defined(CM5)
  223.     CMMD_send_noblock(i, SYNC_MSG, &bm_msg, sizeof(struct bm_rm_msg));
  224.         CMMD_receive(CMMD_ANY_NODE, INITIAL_INFO, (void *) &bm_msg, sizeof(struct bm_rm_msg));
  225. #       endif
  226. #       if defined(NCUBE)
  227.     nwrite(&bm_msg, sizeof(struct bm_rm_msg), i, SYNC_MSG, &unused_flag);
  228.         from = NCUBE_ANY_NODE;
  229.         type = INITIAL_INFO;
  230.         nread(&bm_msg, sizeof(struct bm_rm_msg), &from, &type, &unused_flag);
  231. #       endif
  232.     port = p4_n_to_i(bm_msg.port);
  233.     slave_idx = p4_n_to_i(bm_msg.slave_idx);
  234.     slave_pid = p4_n_to_i(bm_msg.slave_pid);
  235.     switch_port = p4_n_to_i(bm_msg.switch_port);
  236.     /* big master installing local slaves */
  237.     install_in_proctable(0, port, slave_pid, bm_msg.host_name, 
  238.                  slave_idx, P4_MACHINE_TYPE, switch_port);
  239.     p4_global->local_slave_count++;
  240.     }
  241. #   else
  242.     for (slave_idx = 1; slave_idx <= nslaves; slave_idx++)
  243.     {
  244.     p4_dprintfl(20, "creating local slave %d of %d\n",slave_idx,nslaves);
  245.     slave_pid = fork_p4();
  246.     if (slave_pid < 0)
  247.         p4_error("create_bm_processes fork", slave_pid);
  248.     else
  249.         if (slave_pid)
  250.         p4_dprintfl(10, "created local slave %d\n", slave_idx);
  251.     if (slave_pid == 0)    /* At this point, we are the slave. */
  252.     {
  253.         sprintf(whoami_p4, "bm_slave_%d_%d", slave_idx, getpid());
  254.  
  255.         p4_free(p4_local);    /* Doesn't work for weird memory model. */
  256.         p4_local = alloc_local_slave();
  257.  
  258. #           ifdef CAN_DO_SOCKET_MSGS
  259.         if (!(p4_global->local_communication_only))
  260.         {
  261.         p4_local->listener_fd = end_1;
  262.         close(end_2);
  263.         close(listener_fd);
  264.         }
  265.         SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  266. #           endif
  267.  
  268.         /* hang for a valid proctable */
  269.         p4_lock(&p4_global->slave_lock);
  270.         p4_unlock(&p4_global->slave_lock);
  271.  
  272.         p4_local->my_id = p4_get_my_id_from_proc();
  273.         setup_conntab();
  274.         sprintf(whoami_p4, "p%d_%d", p4_local->my_id, getpid());
  275.         usc_init();
  276.  
  277. #           ifdef TCMP
  278.             tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  279. #           endif
  280.  
  281.         /* 
  282.            sync with master twice: once to make sure all slaves have 
  283.            got proctable, and second after the master has synced with the 
  284.            remote processes 
  285.         */
  286.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  287.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  288.  
  289.         p4_dprintfl(20, "local slave starting\n");
  290.         ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  291.         ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  292.         return;
  293.     }
  294.  
  295.     /* master installing local slaves */
  296.     install_in_proctable(0, p4_global->listener_port, slave_pid,
  297.                  p4_global->my_host_name, 
  298.                  slave_idx, P4_MACHINE_TYPE,
  299.                  p4_global->proctable[0].switch_port);
  300.     p4_global->local_slave_count++;
  301.     }
  302. #   endif
  303.  
  304. #   if defined(CM5)
  305.     for (i=nslaves+1; i < CMMD_partition_size(); i++)
  306.         CMMD_send_noblock(i, DIE, &bm_msg, sizeof(struct bm_rm_msg));
  307. #   endif
  308. #   if defined(NCUBE)
  309.     for (i=nslaves+1; i < ncubesize(); i++)
  310.     nwrite(&bm_msg, sizeof(struct bm_rm_msg), i, DIE, &unused_flag);
  311. #   endif
  312.  
  313.  
  314.     /* Done creating slaves. Now fork off the listener */
  315.  
  316. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  317.  
  318. #   ifdef CAN_DO_SOCKET_MSGS
  319.     if (!(p4_global->local_communication_only))
  320.     {
  321.     listener_pid = fork_p4();
  322.     if (listener_pid < 0)
  323.         p4_error("create_bm_processes listener fork", listener_pid);
  324.     if (listener_pid == 0)
  325.     {
  326.         sprintf(whoami_p4, "bm_list_%d", getpid());
  327.         /* Inside listener */
  328.         p4_local = alloc_local_listener();
  329.         l->listening_fd = listener_fd;
  330.         l->slave_fd = end_2;
  331.         close(end_1);
  332.         listener();
  333.         exit(0);
  334.     }
  335.     }
  336. #   endif
  337.  
  338.     /* Else we're still in the big master */
  339.     sprintf(whoami_p4, "p0_%d", getpid());
  340.  
  341.     /* We need to close the fds from the listener setup */
  342. #   ifdef CAN_DO_SOCKET_MSGS
  343.     if (!(p4_global->local_communication_only))
  344.     {
  345.     p4_local->listener_fd = end_1;
  346.     close(listener_fd);
  347.     close(end_2);
  348.     p4_global->listener_pid = listener_pid;
  349.     }
  350. #   endif
  351.  
  352. #   endif
  353.  
  354.     dump_global(80);
  355.     p4_dprintfl(90, "create_bm_processes: exiting\n");
  356.     return (nslaves);
  357. }
  358.  
  359.  
  360. P4VOID procgroup_to_proctable(pg)
  361. struct p4_procgroup *pg;
  362. {
  363.     int i, j, ptidx;
  364.     struct p4_procgroup_entry *pe;
  365.  
  366.     if (strcmp(pg->entries[0].host_name,"local") != 0)
  367.     p4_error("local is not first entry in procgroup ",0);
  368.     strcpy(p4_global->proctable[0].host_name,p4_global->my_host_name);
  369.     get_qualified_hostname(p4_global->proctable[0].host_name);
  370.     p4_global->proctable[0].group_id = 0;
  371.     ptidx = 1;
  372.     for (i=0, pe=pg->entries; i < pg->num_entries; i++, pe++)
  373.     {
  374.     for (j=0; j < pe->numslaves_in_group; j++)
  375.     {
  376.         if (i == 0)
  377.         strcpy(p4_global->proctable[ptidx].host_name,p4_global->my_host_name);
  378.         else
  379.         strcpy(p4_global->proctable[ptidx].host_name,pe->host_name);
  380.         get_qualified_hostname(p4_global->proctable[ptidx].host_name);
  381.         p4_global->proctable[ptidx].group_id = i;
  382.         ptidx++;
  383.     }
  384.     p4_global->num_in_proctable = ptidx;
  385.     }
  386. }
  387.  
  388. P4VOID sync_with_remotes()
  389. {
  390.     struct bm_rm_msg msg;
  391.     int i, fd, node, num_rms, rm[P4_MAXPROCS];
  392.  
  393.     p4_dprintfl(90, "sync_with_remotes: starting\n");
  394.  
  395. #   ifdef CAN_DO_SOCKET_MSGS
  396.     p4_get_cluster_masters(&num_rms, rm);
  397.     for (i = 1; i < num_rms; i++)
  398.     {
  399.     node = rm[i];
  400.     fd = p4_local->conntab[node].port;
  401.     net_recv(fd, &msg, sizeof(msg));
  402.     msg.type = p4_n_to_i(msg.type);
  403.     if (msg.type != SYNC_MSG)
  404.         p4_error("sync_with_remotes: bad type rcvd\n",msg.type);
  405.     }
  406.     for (i = 1; i < num_rms; i++)
  407.     {
  408.     node = rm[i];
  409.     fd = p4_local->conntab[node].port;
  410.     msg.type = p4_i_to_n(SYNC_MSG);
  411.     net_send(fd, &msg, sizeof(msg), FALSE);
  412.     }
  413. #   endif
  414. }
  415.  
  416. P4VOID send_proc_table()
  417. {
  418.     int slave_idx, ent;
  419.     int fd;
  420.     struct bm_rm_msg msg;
  421.     struct proc_info *pe;
  422.  
  423.     p4_dprintfl(90, "send_proc_table: starting\n");
  424.  
  425. #   ifdef CAN_DO_SOCKET_MSGS
  426.     for (slave_idx = 1; slave_idx < p4_global->num_in_proctable; slave_idx++)
  427.     {
  428.     if (p4_global->proctable[slave_idx].slave_idx != 0)
  429.         continue;
  430.  
  431.     fd = p4_local->conntab[slave_idx].port;
  432.  
  433.     p4_dprintfl(90, "sending proctable to slave %d on %d:\n", slave_idx, fd);
  434.     if (fd < 0)
  435.         p4_error("send_proc_table: rm entry doesn't have valid fd", fd);
  436.  
  437.     for (ent = 0, pe = p4_global->proctable;
  438.          ent < p4_global->num_in_proctable; ent++, pe++)
  439.     {
  440.         msg.type = p4_i_to_n(PROC_TABLE_ENTRY);
  441.         msg.port = p4_i_to_n(pe->port);
  442.         msg.unix_id = p4_i_to_n(pe->unix_id);
  443.         msg.slave_idx = p4_i_to_n(pe->slave_idx);
  444.         msg.group_id = p4_i_to_n(pe->group_id);
  445.         strcpy(msg.host_name, pe->host_name);
  446.         strcpy(msg.machine_type,pe->machine_type);
  447.         msg.switch_port = p4_i_to_n(pe->switch_port);
  448.         net_send(fd, &msg, sizeof(msg), FALSE);
  449.     }
  450.     p4_dprintfl(90, "  sending end_of_proc_table\n");
  451.     msg.type = p4_i_to_n(PROC_TABLE_END);
  452.     net_send(fd, &msg, sizeof(msg), FALSE);
  453.     }
  454. #   endif
  455. }
  456.